/**	\author    coidgen 0.9.2
	\version    (1.0 build 16)
	\date      
	\brief     
*/



// Service header info (for version checking),  ! DO NOT CHANGE !
static const char COID_bin_data[] =
"060005000000302E392E3209000000312E342028342E302954070000FF325B4A00000000000000000001000010000000"
"0200000001000000090000004C6F67456E744D6772000000002000000020646972656374206E6F6C6F67206E6F6C6F67"
"5F73797374656D5F63616C6C7300000000080000000800000008000000FFFFFFFF040000006F70636400000000000000"
"000000800000000008000000726561645F6C6F670000000003000000FFFFFFFF0500000075696E747300000000000000"
"0000000408000000FFFFFFFF0500000075696E7473000000000000000000000100000000FFFFFFFF1400000064796E61"
"727261793C6C6F6773747265616D2A3E000000000000000000000208000000010101300000000000000000FFFFFFFF04"
"0000006F7063640000000000000000000080000000000A0000006164645F66696C7465720100000001000000FFFFFFFF"
"12000000636F6E73742046494C5445525F454E5452590000000000000000000011080000000001073000000000000000"
"00FFFFFFFF040000006F7063640000000000000000000080000000000D00000064656C6574655F66696C746572020000"
"0002000000FFFFFFFF0400000075696E74000000000000000000000100000000FFFFFFFF0400000075696E7400000000"
"0000000000000100000000000107300000000000000000FFFFFFFF040000006F70636400000000000000000000800000"
"00000B0000006765745F66696C746572730300000003000000FFFFFFFF0400000075696E740000000000000000000001"
"00000000FFFFFFFF0400000075696E74000000000000000000000100000000FFFFFFFF1600000064796E61727261793C"
"46494C5445525F454E5452593E000000000000000000000208000000010107300000000000000000FFFFFFFF04000000"
"6F7063640000000000000000000080000000000E0000006765745F66696C7465725F6964730400000003000000FFFFFF"
"FF0400000075696E74000000000000000000000100000000FFFFFFFF0400000075696E74000000000000000000000100"
"000000FFFFFFFF0E00000064796E61727261793C75696E743E0000000000000000000002080000000101073000000000"
"00000000FFFFFFFF040000006F7063640000000000000000000080000000000B0000006765745F6C6F675F7570640500"
"000001000000FFFFFFFF0500000075696E7473000000000000000001000204000000010107300000000000000000FFFF"
"FFFF040000006F7063640000000000000000000080000000000D0000006765745F747265655F696E666F060000000200"
"0000FFFFFFFF1300000064796E61727261793C747265655F696E666F3E000000000000000000000208000000FFFFFFFF"
"0500000075696E7473000000000000000001000204000000010107300000000000000000FFFFFFFF040000006F706364"
"000000000000000000008000000000150000006765745F747265655F696E666F5F6368616E6765730700000002000000"
"FFFFFFFF0500000075696E7473000000000000000000000408000000FFFFFFFF1300000064796E61727261793C747265"
"655F696E666F3E00000000000000000000020800000001010730000000000000000001FFFFFFFF040000006F70636400"
"00000000000000000080000000000E0000006163636570745F636F6E6E6563740500008002000000FFFFFFFF0D000000"
"636F6E73742063686172737472000000000000000000001108000000FFFFFFFF0E000000636F6E73742070617373776F"
"726400000000000000000000110800000000008720000000000000000001FFFFFFFF040000006F706364000000000000"
"000000008000000000150000006163636570745F636F6E6E6563745F7368617265640600008000000000000087000000"
"00000000000000000001FFFFFFFF040000006F706364000000000000000000008000000000150000006163636570745F"
"737461727475705F706172616D73FFFF008001000000FFFFFFFF0D000000636D645F696E746572666163650000000000"
"0000000000010800000000008720000000000000000000000001003100FFFFFFFF00000000"
;
//*/


#include "logentmgr.h"
#include "coid/comm/metastream/metastream.h"


namespace coid {


static inline const char ** COID_OUT_ARGS(const char ** from) {
	while( *from ) from++;
	return ++from;
}

typedef ServiceDescriptor::MethodDesc MethodDesc;
#define COID_MethodDesc_constructor(S,I,F)         MethodDesc( S[0], S[1], &S[2], COID_OUT_ARGS(&S[2]), I, F )
#define COID_MethodDesc_constructor_NotImpl        MethodDesc( NULL, NULL, NULL, NULL, 0, 0 )



typedef void (LogEntMgr::*coid_fnc)();

/// fake function, should never be called:
static void coid_throw() {throw ersFE_EXCEPTION;}

/// we need type cast in case there are 2 or more methods with the same name
#define COID_DISPATCH_CREATE_HOOK(M,i,t,tc) \
	if( i < coid_fnc_count ) { \
		if( (coid_flags[i] & COID_LogEntMgr_method_desc[i].flags & MethodDesc::xACCESS_MODE) ) \
			coid_fnc_table[t] = (coid_fnc) (tc) &LogEntMgr::M; \
		else *(void **) &coid_fnc_table[t] = (void *) coid_throw; \
	}


#define COID_DISPATCH_CREATE_CALLER_HOOK(M,i,t) \
	if( i < coid_fnc_count ) { \
		if( (coid_flags[i] & COID_LogEntMgr_method_desc[i].flags & MethodDesc::xACCESS_MODE) ) \
			coid_fnc_table[t] = (coid_fnc) &DISPATCH_CALLER_LogEntMgr_1_0::M; \
		else *(void **) &coid_fnc_table[t] = (void *) coid_throw; \
	}






/// functions:
uint COID_LogEntMgr_1_0_get_method_id( const token & name );
opcd COID_LogEntMgr_1_0_dispatch( InstanceData * _coid_inst_data, uint _coid_fnc_id, binstream& _coid_bstr, metastream* coid_meta=0 );
metastream& COID_LogEntMgr_1_0_getmeta();



struct DISPATCH_CALLER_LogEntMgr_1_0
{
	void call_dispatch( binstream * b ) {
		COID_CLIENT_EXESTREAM_ARGS * a = (COID_CLIENT_EXESTREAM_ARGS *) this;
		InstanceData d;  d._object = a->obj;
		COID_LogEntMgr_1_0_dispatch( &d, a->id, *b );
	}
};





enum {	/// command ids, format is: COID_classname_fncname_fncid
	COID_LogEntMgr_read_log_0 = 0,
	COID_LogEntMgr_add_filter_1 = 1,
	COID_LogEntMgr_delete_filter_2 = 2,
	COID_LogEntMgr_get_filters_3 = 3,
	COID_LogEntMgr_get_filter_ids_4 = 4,
	COID_LogEntMgr_get_log_upd_5 = 5,
	COID_LogEntMgr_get_tree_info_6 = 6,
	COID_LogEntMgr_get_tree_info_changes_7 = 7,

    COID_LogEntMgr_accept_connect_5,
    COID_LogEntMgr_accept_connect_shared_6
};



/// info about every function:
static const char * COID_LogEntMgr_read_log_0_finfo[] = {"read_log", "opcd ", "uints & ref", "uints max", NULL, "uints & ref", "dynarray<logstream*> & list", NULL};
static const char * COID_LogEntMgr_add_filter_1_finfo[] = {"add_filter", "opcd ", "const FILTER_ENTRY & flt", NULL, NULL};
static const char * COID_LogEntMgr_delete_filter_2_finfo[] = {"delete_filter", "opcd ", "uint obj", "uint fltn", NULL, NULL};
static const char * COID_LogEntMgr_get_filters_3_finfo[] = {"get_filters", "opcd ", "uint obj", "uint fltn", NULL, "dynarray<FILTER_ENTRY> & out", NULL};
static const char * COID_LogEntMgr_get_filter_ids_4_finfo[] = {"get_filter_ids", "opcd ", "uint obj", "uint fltn", NULL, "dynarray<uint> & out", NULL};
static const char * COID_LogEntMgr_get_log_upd_5_finfo[] = {"get_log_upd", "opcd ", NULL, "uints * ref", NULL};
static const char * COID_LogEntMgr_get_tree_info_6_finfo[] = {"get_tree_info", "opcd ", NULL, "dynarray<tree_info> & out", "uints * ref", NULL};
static const char * COID_LogEntMgr_get_tree_info_changes_7_finfo[] = {"get_tree_info_changes", "opcd ", "uints & ref", NULL, "uints & ref", "dynarray<tree_info> & out", NULL};
static const char * COID_LogEntMgr_accept_connect_5_finfo[] = {"accept_connect", "opcd ", "const charstr & name", "const password & pwd", NULL, NULL};
static const char * COID_LogEntMgr_accept_connect_shared_6_finfo[] = {"accept_connect_shared", "opcd ", NULL, NULL};


/// create structure that holds everything about function:
static const MethodDesc COID_LogEntMgr_method_desc[] = {
	COID_MethodDesc_constructor( COID_LogEntMgr_read_log_0_finfo, 0x00000000, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fCONST ),
	COID_MethodDesc_constructor( COID_LogEntMgr_add_filter_1_finfo, 0x00000001, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE ),
	COID_MethodDesc_constructor( COID_LogEntMgr_delete_filter_2_finfo, 0x00000002, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE ),
	COID_MethodDesc_constructor( COID_LogEntMgr_get_filters_3_finfo, 0x00000003, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE | MethodDesc::fCONST ),
	COID_MethodDesc_constructor( COID_LogEntMgr_get_filter_ids_4_finfo, 0x00000004, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE | MethodDesc::fCONST ),
	COID_MethodDesc_constructor( COID_LogEntMgr_get_log_upd_5_finfo, 0x00000005, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE | MethodDesc::fCONST ),
	COID_MethodDesc_constructor( COID_LogEntMgr_get_tree_info_6_finfo, 0x00000006, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE | MethodDesc::fCONST ),
	COID_MethodDesc_constructor( COID_LogEntMgr_get_tree_info_changes_7_finfo, 0x00000007, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE | MethodDesc::fCONST ),
	COID_MethodDesc_constructor( COID_LogEntMgr_accept_connect_5_finfo, 0x80000005, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE | MethodDesc::fLOG_CALL ),
	COID_MethodDesc_constructor( COID_LogEntMgr_accept_connect_shared_6_finfo, 0x80000006, MethodDesc::fACCESS_MODE_DIRECT | MethodDesc::fACCESS_MODE_INTERPROCESS | MethodDesc::fACCESS_MODE_REMOTE | MethodDesc::fLOG_CALL )
};



static const char * COID_dependencies_LogEntMgr[] = {

	NULL
};


/// ServiceDescriptor:
static ServiceDescriptor COID_descriptor_LogEntMgr;



/// dispatch stores function tables for all 'direct' clients with different minor versions here
class COID_register_LogEntMgr_1_0
{
	struct table {
		uint ver;
		coid_fnc * tbl;
	};
	dynarray<table>	_tables;

public:
//	comm_mutex_rw	_mx;
	comm_mutex	_mx;
   const void* (*dummyreg)();

	COID_register_LogEntMgr_1_0() {
		COID_descriptor_LogEntMgr._version.set( "", 1, 0, 16 );
		COID_descriptor_LogEntMgr._coid_version = COID_VERSION;
		COID_descriptor_LogEntMgr._name = "LogEntMgr";
		COID_descriptor_LogEntMgr._shortname = "LogEntMg";
		COID_descriptor_LogEntMgr._info = " COID Log manager service";
		COID_descriptor_LogEntMgr._dependencies = COID_dependencies_LogEntMgr;
		COID_descriptor_LogEntMgr._nmeth = 8;
		COID_descriptor_LogEntMgr._methflags = COID_LogEntMgr_method_desc;
		COID_descriptor_LogEntMgr._flags = ServiceDescriptor::fALLOW_DIRECT_ACCESS | ServiceDescriptor::fAUTONOMOUS;
		COID_descriptor_LogEntMgr._acceptor_port = (uint) -1;
		COID_descriptor_LogEntMgr._bin_svc_data = COID_bin_data;
		COID_descriptor_LogEntMgr.get_method_id = COID_LogEntMgr_1_0_get_method_id;
		COID_descriptor_LogEntMgr.dispatch = COID_LogEntMgr_1_0_dispatch;
		COID_descriptor_LogEntMgr._fnc_get_meta = COID_LogEntMgr_1_0_getmeta;
#ifdef _DEBUG
		COID_descriptor_LogEntMgr._flags |= ServiceDescriptor::fDEBUG;
#endif
		_mx.set_name( "COID_register_LogEntMgr_1_0" );
		INTERFACE_REGISTER(ServiceDescriptor).add( &COID_descriptor_LogEntMgr );
	}

	~COID_register_LogEntMgr_1_0() {
//		MXGUARDRW( (comm_mutex_rw &) _mx );
		MXGUARD( (comm_mutex &) _mx );
		for( uint i=0; i<_tables.size(); i++ )
			delete [] _tables[i].tbl;
	}
	coid_fnc * get_table_notlocked( uint ver ) {
		for( uint i=0; i<_tables.size(); i++ )
			if( ver == _tables[i].ver ) return _tables[i].tbl;
		return NULL;
	}
	coid_fnc * get_table( uint ver ) {
//		MXGUARDRW( (const comm_mutex_rw &) _mx );		/// ==> read lock
		MXGUARD( (const comm_mutex &) _mx );
		return get_table_notlocked( ver );
	}
	void insert_table( uint ver, coid_fnc * tbl ) {
		table * t = _tables.add( 1 );	/// mutex has been locked
		t->ver = ver; t->tbl = tbl;
	}
};


// for dll linking
COID_register_LogEntMgr_1_0 & get_COID_register_LogEntMgr_1_0()
{
	static COID_register_LogEntMgr_1_0 x;
	x.dummyreg = &COID_GET_FN;    //force exporting the symbol
	x.dummyreg();
	return x;
}

//for static linking (must be called from outside to link this object)
void get_COID_register_LogEntMgr()
{
	COID_register_LogEntMgr_1_0();
}

static COID_register_LogEntMgr_1_0 & COID_auto_register_variable = get_COID_register_LogEntMgr_1_0();





metastream& COID_LogEntMgr_1_0_getmeta()
{
    static metastream* meta = 0;
    if(meta)  return *meta;

    meta = new metastream;
#define META_TD(TY)     metastream::TypeDesc< TY >::get_str(*meta)


    return *meta;
}



///////////////////////////////////////////////////////////////////////////////
opcd COID_LogEntMgr_1_0_dispatch( InstanceData* _coid_inst_data, uint _coid_fnc_id, binstream& _coid_bstr, metastream* coid_meta )
{
	LogEntMgr * _coid_LogEntMgr_obj = (LogEntMgr *) _coid_inst_data->_object;
	double _coid_LogEntMgr_ticks = 0.0;
	binstream * _coid_log = NULL;
	opcd _coid_err_code = 0;

	switch( _coid_fnc_id ) {
		case StdDispatchMethod::CONSTRUCTOR: {
			_coid_inst_data->_object = _coid_LogEntMgr_obj = new LogEntMgr;
       } break;
		case StdDispatchMethod::POSTCONSTRUCTOR: {
			_coid_err_code = _coid_LogEntMgr_obj->accept_startup_params( *_coid_inst_data->_cmdin );
		} break;
		case StdDispatchMethod::DESTRUCTOR: {
			delete _coid_LogEntMgr_obj; _coid_inst_data->_object = NULL;
		} break;
		case StdDispatchMethod::CREATE_INTERFACE: {
			CreateInterfaceInfo* coid_iface_info;
			_coid_bstr.read_ptr(coid_iface_info);
			const uint coid_fnc_count = coid_iface_info->_nmethods;
			const uint * coid_flags = coid_iface_info->_methflags;
			coid_fnc * coid_fnc_table = get_COID_register_LogEntMgr_1_0().get_table( coid_iface_info->_clientver.get_minor() );

			if( !coid_fnc_table ) {
				//MXGUARDRW( get_COID_register_LogEntMgr_1_0()._mx );
				MXGUARD( get_COID_register_LogEntMgr_1_0()._mx );
				coid_fnc_table = get_COID_register_LogEntMgr_1_0().get_table_notlocked( coid_iface_info->_clientver.get_minor() );
				if( !coid_fnc_table ) {
					coid_fnc_table = (coid_fnc *) new char[ sizeof(coid_fnc) * (coid_fnc_count + 1) ];	/// new coid_fnc[...] would allocate pointer to 0 bytes (M$ 'feature')
					memset( coid_fnc_table, 0, (coid_fnc_count + 1) * sizeof(coid_fnc) );
					uint coid_table_index = 0;

					((CreateInterfaceInfo::t_fnc *) coid_fnc_table)[coid_table_index++] = coid_iface_info->_disconnect_interface;
					COID_DISPATCH_CREATE_HOOK( read_log, 0, coid_table_index++, opcd (LogEntMgr::*)( uints & , uints , dynarray<logstream*> &  ) const )
					COID_DISPATCH_CREATE_HOOK( add_filter, 1, coid_table_index++, opcd (LogEntMgr::*)( const FILTER_ENTRY &  ) )
					COID_DISPATCH_CREATE_HOOK( delete_filter, 2, coid_table_index++, opcd (LogEntMgr::*)( uint , uint  ) )
					COID_DISPATCH_CREATE_HOOK( get_filters, 3, coid_table_index++, opcd (LogEntMgr::*)( uint , uint , dynarray<FILTER_ENTRY> &  ) const )
					COID_DISPATCH_CREATE_HOOK( get_filter_ids, 4, coid_table_index++, opcd (LogEntMgr::*)( uint , uint , dynarray<uint> &  ) const )
					COID_DISPATCH_CREATE_HOOK( get_log_upd, 5, coid_table_index++, opcd (LogEntMgr::*)( uints *  ) const )
					COID_DISPATCH_CREATE_HOOK( get_tree_info, 6, coid_table_index++, opcd (LogEntMgr::*)( dynarray<tree_info> & , uints *  ) const )
					COID_DISPATCH_CREATE_HOOK( get_tree_info_changes, 7, coid_table_index++, opcd (LogEntMgr::*)( uints & , dynarray<tree_info> &  ) const )

					get_COID_register_LogEntMgr_1_0().insert_table( coid_iface_info->_clientver.get_minor(), coid_fnc_table );
				}
			}

			_coid_bstr.acknowledge();
			_coid_bstr.write_ptr( coid_fnc_table );
			_coid_bstr.write_ptr( _coid_inst_data->_object );
			_coid_bstr.write_ptr( coid_iface_info->_mutex );
		} break;
		case StdDispatchMethod::AUTHENTIFY: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			
			charstr name;
			_coid_bstr >> name;
			password pwd;
			_coid_bstr >> pwd;

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << "80000005" << ") accept_connect ( "; *_coid_log << name; *_coid_log << ", "; *_coid_log << pwd; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->accept_connect( name, pwd );
			_coid_bstr << _coid_err_code;
			

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;
		case StdDispatchMethod::AUTHENTIFY_SHARED: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << "80000006" << ") accept_connect_shared ( "; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->accept_connect_shared(  );
			_coid_bstr << _coid_err_code;
			

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;
		case StdDispatchMethod::AUTHENTIFY_AUTO: {
			_coid_bstr.acknowledge();
			_coid_bstr << _coid_err_code;
			_coid_bstr.flush();
			return ersNOT_IMPLEMENTED;
		} break;
		case StdDispatchMethod::HANDLE_NET_LOOP: {
			return ersNOT_IMPLEMENTED;
		} break;
		case StdDispatchMethod::PREDESTRUCTOR: {
			_coid_bstr.acknowledge();
			_coid_bstr << _coid_err_code;
			_coid_bstr.flush();
			return ersNOT_IMPLEMENTED;
		} break;
		case StdDispatchMethod::COMMAND: {
			_coid_bstr.acknowledge();
			_coid_bstr << _coid_err_code;
			_coid_bstr.flush();
			return ersNOT_IMPLEMENTED;
		} break;
		case StdDispatchMethod::SPAWN: {
			_coid_bstr.acknowledge();
			_coid_bstr << _coid_err_code;
			_coid_bstr.flush();
			return ersNOT_IMPLEMENTED;
		} break;
		case StdDispatchMethod::ECHO: {
			_coid_bstr.acknowledge();
			_coid_bstr << _coid_err_code;
			_coid_bstr.flush();
			return ersNOT_IMPLEMENTED;
		} break;


		/// service-specific methods:
		case COID_LogEntMgr_add_filter_1: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			
			FILTER_ENTRY flt;
			_coid_bstr >> flt;

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << COID_LogEntMgr_add_filter_1 << ") add_filter ( "; *_coid_log << flt; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->add_filter( flt );
			_coid_bstr << _coid_err_code;
			
			_coid_bstr.flush();

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;
		case COID_LogEntMgr_delete_filter_2: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			
			uint obj;
			_coid_bstr >> obj;
			uint fltn;
			_coid_bstr >> fltn;

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << COID_LogEntMgr_delete_filter_2 << ") delete_filter ( "; *_coid_log << obj; *_coid_log << ", "; *_coid_log << fltn; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->delete_filter( obj, fltn );
			_coid_bstr << _coid_err_code;
			
			_coid_bstr.flush();

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;
		case COID_LogEntMgr_get_filters_3: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			
			uint obj;
			_coid_bstr >> obj;
			uint fltn;
			_coid_bstr >> fltn;
			dynarray<FILTER_ENTRY> out;

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << COID_LogEntMgr_get_filters_3 << ") get_filters ( "; *_coid_log << obj; *_coid_log << ", "; *_coid_log << fltn; *_coid_log << ", "; *_coid_log << "?"; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->get_filters( obj, fltn, out );
			_coid_bstr << _coid_err_code;
			if( ! _coid_err_code ) {
				_coid_bstr << out;
			}

			_coid_bstr.flush();

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << out; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;
		case COID_LogEntMgr_get_filter_ids_4: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			
			uint obj;
			_coid_bstr >> obj;
			uint fltn;
			_coid_bstr >> fltn;
			dynarray<uint> out;

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << COID_LogEntMgr_get_filter_ids_4 << ") get_filter_ids ( "; *_coid_log << obj; *_coid_log << ", "; *_coid_log << fltn; *_coid_log << ", "; *_coid_log << "?"; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->get_filter_ids( obj, fltn, out );
			_coid_bstr << _coid_err_code;
			if( ! _coid_err_code ) {
				_coid_bstr << out;
			}

			_coid_bstr.flush();

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << out; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;
		case COID_LogEntMgr_get_log_upd_5: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			
			uints ref;

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << COID_LogEntMgr_get_log_upd_5 << ") get_log_upd ( "; *_coid_log << "?"; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->get_log_upd( &ref );
			_coid_bstr << _coid_err_code;
			if( ! _coid_err_code ) {
				_coid_bstr << ref;
			}

			_coid_bstr.flush();

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << ref; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;
		case COID_LogEntMgr_get_tree_info_6: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			
			dynarray<tree_info> out;
			uints ref;

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << COID_LogEntMgr_get_tree_info_6 << ") get_tree_info ( "; *_coid_log << "?"; *_coid_log << ", "; *_coid_log << "?"; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->get_tree_info( out, &ref );
			_coid_bstr << _coid_err_code;
			if( ! _coid_err_code ) {
				_coid_bstr << out;
				_coid_bstr << ref;
			}

			_coid_bstr.flush();

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << out; *_coid_log << ", "; *_coid_log << ref; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;
		case COID_LogEntMgr_get_tree_info_changes_7: {
			if( (_coid_inst_data->_flags & (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION)) == (MethodDesc::fLOG_CALL | MethodDesc::fLOG_DURATION) )
				_coid_LogEntMgr_ticks = SINGLETON(HPTIMER).ftime();
			
			uints ref;
			_coid_bstr >> ref;
			dynarray<tree_info> out;

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				_coid_log = &_coid_inst_data->_cmdin->post_method();
				*_coid_log << "(" << COID_LogEntMgr_get_tree_info_changes_7 << ") get_tree_info_changes ( "; *_coid_log << ref; *_coid_log << ", "; *_coid_log << "?"; *_coid_log << " )";
			}

			_coid_bstr.acknowledge();

			_coid_err_code = _coid_LogEntMgr_obj->get_tree_info_changes( ref, out );
			_coid_bstr << _coid_err_code;
			if( ! _coid_err_code ) {
				_coid_bstr << ref;
				_coid_bstr << out;
			}

			_coid_bstr.flush();

			if( _coid_inst_data->_flags & MethodDesc::fLOG_CALL ) {
				*_coid_log << "  -->  ("; *_coid_log << ref; *_coid_log << ", "; *_coid_log << out; *_coid_log << ")";
				if( _coid_inst_data->_flags & MethodDesc::fLOG_DURATION )
					*_coid_log << " [" << (SINGLETON(HPTIMER).ftime() - _coid_LogEntMgr_ticks) * 1000 << "]";
				if( !_coid_err_code ) *_coid_log << " .. ok" << EOM;
				else *_coid_log << " .. fail: " << opcd_formatter(_coid_err_code) << EOM;
			}
			
		} break;


		default:
			_coid_bstr.acknowledge( true );
			_coid_bstr << ersNOT_IMPLEMENTED;
			_coid_bstr.flush();
			return ersNOT_IMPLEMENTED;
		break;
	}



	return _coid_err_code;
}












/// method table
static METHOD_TABLE COID_LogEntMgr_method_table[] = {
	{NULL, UMAX32},
	{"get_filter_ids", COID_LogEntMgr_get_filter_ids_4},
	{"get_log_upd", COID_LogEntMgr_get_log_upd_5},
	{"get_tree_info", COID_LogEntMgr_get_tree_info_6},
	{NULL, UMAX32},
	{NULL, UMAX32},
	{"add_filter", COID_LogEntMgr_add_filter_1},
	{"read_log", COID_LogEntMgr_read_log_0},
	{"delete_filter", COID_LogEntMgr_delete_filter_2},
	{"get_tree_info_changes", COID_LogEntMgr_get_tree_info_changes_7},
	{NULL, UMAX32},
	{"get_filters", COID_LogEntMgr_get_filters_3}
};



#define COID_dispatch_method_size		(sizeof(COID_LogEntMgr_method_table) / sizeof(METHOD_TABLE))



uint COID_LogEntMgr_1_0_get_method_id( const token & name )
{
	hash<token> mha;
	uints idx = mha(name) % COID_dispatch_method_size;

	for( uints i=0; i<COID_dispatch_method_size; i++ ) {
		if( COID_LogEntMgr_method_table[idx].name )
			if( name == COID_LogEntMgr_method_table[idx].name )
				return COID_LogEntMgr_method_table[idx].id;
		idx++;
		if( idx == COID_dispatch_method_size ) idx = 0;
	}

	return UMAX32;
}


} // namespace coid
